<template>
  <HeadContainer
    class="upload bg-background"
    :title="headTitle"
    :show-trash="isUpdate"
    @back="cancelPublish"
    @trash="remove"
  >
    <div class="form gap-col-16">
      <UploadStatus @video-overlimit="onVideoOverlimit" @upload-fail="onUploadFail"></UploadStatus>
      <InputWrap v-model="publishParams.content" :label="$t('info.description')" :err-msg="contentError"></InputWrap>
      <TagEditor v-model="publishParams.tags" :err-msg="tagError"></TagEditor>
      <!-- <div class="target gap-col-5">
        <label class="font-size-12 font-weight-400 line-height-120">
          {{ $t('info.audience') }}
          <span class="font-size-12 font-weight-400 line-height-120 text-subtitle-x">
            {{ $t('info.multipleChoice') }}
          </span>
        </label>
        <div class="btns gap-row-8">
          <button
            class="cancel-light-btn font-size-12 font-weight-500 line-height-140"
            :class="{ 'hollow-btn': publishParams.attribute.includes(INTERESTED_IN.STRAIGHT) }"
            @click="toggleTarget(INTERESTED_IN.STRAIGHT)"
          >
            {{ $t('interestedIn.straight') }}
          </button>
          <button
            class="cancel-light-btn font-size-12 font-weight-500 line-height-140"
            :class="{ 'hollow-btn': publishParams.attribute.includes(INTERESTED_IN.GAY) }"
            @click="toggleTarget(INTERESTED_IN.GAY)"
          >
            {{ $t('interestedIn.gay') }}
          </button>
          <button
            class="cancel-light-btn font-size-12 font-weight-500 line-height-140"
            :class="{ 'hollow-btn': publishParams.attribute.includes(INTERESTED_IN.LESBIAN) }"
            @click="toggleTarget(INTERESTED_IN.LESBIAN)"
          >
            {{ $t('interestedIn.lesbian') }}
          </button>
          <button
            class="cancel-light-btn font-size-12 font-weight-500 line-height-140"
            :class="{ 'hollow-btn': publishParams.attribute.includes(INTERESTED_IN.TRANS) }"
            @click="toggleTarget(INTERESTED_IN.TRANS)"
          >
            {{ $t('interestedIn.trans') }}
          </button>
        </div>
      </div> -->
      <div class="permision gap-col-5">
        <label class="font-size-12 font-weight-400 line-height-120">{{ $t('info.appear') }}</label>
        <div class="btns gap-row-8">
          <button
            class="cancel-light-btn font-size-12 font-weight-500 line-height-140"
            :class="{ 'hollow-btn': publishParams.visible === FEED_PERMISION.ALL }"
            @click="publishParams.visible = FEED_PERMISION.ALL"
          >
            {{ $t('info.media.free') }}
          </button>
          <button
            class="cancel-light-btn font-size-12 font-weight-500 line-height-140"
            :class="{ 'hollow-btn': publishParams.visible === FEED_PERMISION.SUB }"
            @click="publishParams.visible = FEED_PERMISION.SUB"
          >
            {{ $t('info.media.subs') }}
          </button>
          <button
            class="cancel-light-btn font-size-12 font-weight-500 line-height-140"
            :class="{ 'hollow-btn': publishParams.visible === FEED_PERMISION.SHOP }"
            @click="publishParams.visible = FEED_PERMISION.SHOP"
          >
            {{ $t('info.media.shop') }}
          </button>
        </div>
      </div>
      <InputWrap
        v-if="publishParams.visible === FEED_PERMISION.SHOP"
        v-model="publishParams.money"
        :label="$t('info.subAmount')"
        :err-msg="moneyError"
        number
      ></InputWrap>
      <div v-if="isCreate || publishTimeOpen" class="publish-time-wrap gap-col-5">
        <div class="title gap-row-8">
          <label class="label font-size-14 font-weight-400 line-height-140">{{ $t('info.schedulePublish') }}</label>
          <InputSwitch class="input-switch" v-model="publishTimeOpen"></InputSwitch>
        </div>
        <DateTimeInput v-if="publishTimeOpen" v-model="publishParams.postTime"></DateTimeInput>
      </div>
      <div class="divider"></div>
      <div class="btns gap-row-16">
        <button class="cancel-light-btn full" @click="cancelPublish">{{ $t('common.cancel') }}</button>
        <button class="primary-btn full" :disabled="publishDisable" @click="publish">
          {{ isUpdate ? $t('common.save') : $t('common.publish') }}
        </button>
      </div>
    </div>
  </HeadContainer>
</template>

<script setup>
import { computed, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import { storeToRefs } from 'pinia'
import { usePopupDialogStore } from '@/store/popup-dialog'
import { usePopupMessageStore } from '@/store/popup-message'
import { usePublishStore } from '@/store/publish'
import { $t } from '@/i18n'
import { parseError, useYup } from '@/plugins/yup'
import { toDateTimeString } from '@/utils/string-helper'
import DateTimeInput from '@/components/form/DateTimeInput.vue'
import InputSwitch from '@/components/form/InputSwitch.vue'
import InputWrap from '@/components/form/InputWrap.vue'
import TagEditor from '@/components/form/TagEditor.vue'
import HeadContainer from '@/components/layout/HeadContainer.vue'
import {
  /* INTERESTED_IN, */
  FEED_PERMISION,
} from '@/constant'
import { SERVICE_NAME, UPLOAD_STATUS } from '@/constant/publish'
import API from '@/http'
import UploadStatus from './UploadStatus.vue'

const { $alert, $confirm } = usePopupDialogStore()
const { open: openMessage } = usePopupMessageStore()

const emits = defineEmits(['complete', 'cancel'])

// Head title
const publishStore = usePublishStore()
const { onFileInput, uploadFiles, isCreate, isUpdate, isVideo, isImage, publishTimeOpen } = storeToRefs(publishStore)
const { publishParams, getUploadPayload } = publishStore
const headTitle = ref($t('info.upload.media'))
watch(onFileInput, (v) => {
  if (v) {
    const { service } = getUploadPayload()
    headTitle.value = SERVICE_NAME[service] || $t('info.upload.media')
  }
})
watch(isUpdate, (v) => {
  headTitle.value = v ? $t('title.media') : $t('info.upload.media')
})

const publishing = ref(false)
const publishDisable = computed(() => publishing.value)

const router = useRouter()
function cancelPublish() {
  if (isUpdate.value) {
    router.replace({ name: 'mine' }).then(() => emits('cancel'))
  } else {
    $confirm({
      title: $t('title.cancelPublish'),
      content: $t('content.cancelPublish'),
      confirm: () => {
        emits('cancel')
      },
      cancel: () => {},
    }).open()
  }
}

function onVideoOverlimit() {
  $alert({
    title: $t('content.uploadVideoLimit.videoOverlimit'),
    content: $t('content.uploadVideoLimit.videoCannotOver'),
    confirm: () => {
      emits('cancel')
    },
    showClose: false,
  }).open()
}

function onUploadFail(msg) {
  $alert({
    title: $t('content.uploadFail'),
    content: msg,
    confirm: () => {
      emits('cancel')
    },
    showClose: false,
  }).open()
}

// function toggleTarget(target) {
//   const index = publishParams.attribute.indexOf(target)
//   if (index === -1) {
//     publishParams.attribute.push(target)
//     publishParams.attribute.sort((a, b) => a - b)
//   } else {
//     if (publishParams.attribute.length > 1) {
//       publishParams.attribute.splice(index, 1)
//     }
//   }
// }

function publish() {
  if (isUpdate.value) {
    update()
  } else {
    create()
  }
}

function create() {
  if (!validation()) return

  const data = makeReqData()

  publishing.value = true
  API.Publish.create({ data })
    .then((d) => {
      $alert({
        title: $t('content.publish.createSuccess'),
        confirm: () => {
          emits('complete')
        },
        fromCenter: true,
      }).open()
    })
    .catch((e) => {
      $alert({
        title: $t('content.publish.createFail'),
        content: e.message,
        confirm: () => {},
      }).open()
    })
    .finally(() => (publishing.value = false))
}

function update() {
  if (!validation()) return

  const data = makeReqData()

  publishing.value = true
  API.Publish.update({ data })
    .then((d) => {
      $alert({
        title: $t('content.publish.updateSuccess'),
        confirm: () => {
          router.replace({ name: 'mine' }).then(() => emits('complete'))
        },
        fromCenter: true,
      }).open()
    })
    .catch((e) => {
      $alert({
        title: $t('content.publish.updateFail'),
        content: e.message,
        confirm: () => {},
      }).open()
    })
    .finally(() => (publishing.value = false))
}

function remove() {
  $confirm({
    title: $t('content.publish.deleteMedia'),
    content: $t('content.publish.sureToDelete'),
    confirm: () => {
      const data = { id: publishParams.id }
      publishing.value = true
      API.Publish.delete({ data })
        .then((d) => {
          openMessage($t('content.publish.deleteSuccess'))
          router.replace({ name: 'mine' }).then(() => emits('complete'))
        })
        .catch((e) => {
          openMessage($t('content.publish.deleteFail'))
        })
        .finally(() => (publishing.value = false))
    },
    cancel: () => {},
  }).open()
}

function makeReqData() {
  const data = {
    type: publishParams.type,
    shape: publishParams.shape,
    content: publishParams.content,
    tags: publishParams.tags.join(','),
    attribute: publishParams.attribute.join(','),
    visible: publishParams.visible,
  }
  if (isUpdate.value) {
    data.id = publishParams.id
  }
  if (isVideo.value && [FEED_PERMISION.SUB, FEED_PERMISION.SHOP].includes(publishParams.visible)) {
    data.open_preview = publishParams.openPreview
  }
  if (publishParams.visible === FEED_PERMISION.SHOP) {
    data.money = parseFloat(publishParams.money)
  }
  if (publishTimeOpen.value) {
    data.local_time = toDateTimeString(new Date())
    data.post_time = toDateTimeString(publishParams.postTime)
  }
  if (isVideo.value) {
    data.video_path = publishParams.videoPath
    data.video_time = publishParams.videoTime
  }
  if (isImage.value) {
    const [{ url, width, height }, ...rest] = uploadFiles.value
    data.img_path = url
    data.img_width = width
    data.img_height = height
    data.img_more = rest.map(({ url, width, height }) => ({ url, width, height }))
  }
  return data
}

const yup = useYup()
const contentSchema = yup.string().min(2).max(300)
const contentError = ref('')
const tagError = ref('')
const moneySchema = yup.number().positive().max(500)
const moneyError = ref('')
function validation() {
  let result = true

  if (uploadFiles.value.length === 0) {
    $alert({
      title: $t('common.error'),
      content: $t('content.publish.noFile'),
      confirm: () => {},
      showClose: false,
      fromCenter: true,
    }).open()

    result = false
    return result
  }

  if (!uploadFiles.value.every((o) => o.status === UPLOAD_STATUS.DONE || o.status === UPLOAD_STATUS.SAVE)) {
    const undoneSeqArr = []
    uploadFiles.value.forEach((o, i) => {
      if (o.status !== UPLOAD_STATUS.DONE && o.status !== UPLOAD_STATUS.SAVE) {
        undoneSeqArr.push(i + 1)
      }
    })
    $alert({
      title: $t('common.error'),
      content: $t('content.publish.foundFailFiles', { index: undoneSeqArr.join(', ') }),
      confirm: () => {},
      showClose: false,
      fromCenter: true,
    }).open()

    result = false
    return result
  }

  moneyError.value = ''
  if (publishParams.visible === FEED_PERMISION.SHOP) {
    try {
      moneySchema.validateSync(publishParams.money)
    } catch (e) {
      moneyError.value = parseError(e)
      result = false
    }
  }

  contentError.value = ''
  try {
    contentSchema.validateSync(publishParams.content)
  } catch (e) {
    contentError.value = parseError(e)
    result = false
  }

  tagError.value = ''
  if (publishParams.tags.length < 1) {
    tagError.value = $t('info.publishTagLessCount', { count: 1 })
    result = false
  }
  if (publishParams.tags.length > 10) {
    tagError.value = $t('info.publishTagMoreCount', { count: 10 })
    result = false
  }

  return result
}
</script>

<style lang="scss" scoped>
.upload {
  .form {
    display: flex;
    flex-direction: column;

    .target,
    .permision,
    .publish-time-wrap {
      display: flex;
      flex-direction: column;
    }

    .publish-time-wrap {
      .title {
        display: flex;
        .label {
          flex-grow: 1;
        }

        // 估計是 <InputSwitch> 內部寬度有問題會造成跑版，只好自己調回來
        .input-switch {
          transform: translateX(-0.1rem);
        }
      }
    }

    .divider {
      height: 1px;
      background-color: rgba(255, 255, 255, 0.27);
    }

    .btns {
      display: flex;

      .full {
        flex-grow: 1;
      }

      .hollow-btn {
        padding: 0 0.875rem;
        border-width: 0.125rem;
      }
    }
  }
}
</style>
